/*
  Name: CheckSum calculator
  Copyright: 
  Author: JackyCA.Liu
  Date: 08/07/11 09:29
  Description: The checksum algorithm used is the 8-Bit 
  Fletcher Algorithm, which is used in the TCP standard
*/

/* Algorithm

CK_A = 0, CK_B = 0
For(I=0;I<N;I++)
{
  CK_A = CK_A + Buffer[I]
  CK_B = CK_B + CK_A
}

B5 62 
input data:   06 01 08 00 01 06 01 01 01 01 01 00
checksum:     1B E9

*/

/*Input example:06 01 08 00 01 06 01 01 01 01 01 00
 Output example:B5 62 06 01 08 00 01 06 01 01 01 01 01 00 1B E9
 Last two block in output example is the checksum. 
*/

#include <StdAfx.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "checksum.h"

int MyAtoi(char num1, char num2) {
    int sum = 0;
    char zero = '0';
    char nine = '9';
    char charA = 'A';
    char charZ = 'Z';
    
    if(isalpha(num1)) {
        sum+=(num1-charA+10)*16;                  
    } else {
        sum+=(num1-zero)*16;
    }
    if(isalpha(num2)) {
        sum+=num2-charA+10;                  
    } else {
        sum+=num2-zero;
    }
    return sum;
}

//convert string data into integer
void convertToBuffer(char *str, int *buffer, int I) {
    int i=0;
    for(i=0; i<I; i++){
        buffer[i] = MyAtoi(str[3*i], str[3*i+1]);
    }
}

//use converted buffer integer data to calculate checksum
void checkSum(int *buffer, int I, int *CK_A, int *CK_B) {
    int i=0;
    for(i=0;i<I;i++)
    {
        *CK_A = *CK_A + buffer[i];
        *CK_B = *CK_B + *CK_A;
    }     
}

void printElement(BYTE *ByteCommand, int section_num) {
    int i=0;
    for(i=0; i<section_num; i++) {        
		if(i==section_num-1)
			printf("%02X", ByteCommand[i]);   
		else
			printf("%02X ", ByteCommand[i]);   
    } 
}


//public
int generateCommand(char *StrCommand, BYTE** ByteCommand){
    int section_num = 0;
    int buffer[SIZE];
    int CK_A = 0;
    int CK_B = 0;
    int mask = MyAtoi('F','F');
    
    section_num = (strlen(StrCommand)-2)/STR_BLOCK_SIZE + 1; //section number
        
    convertToBuffer(StrCommand, buffer, section_num);
        
    CK_A = 0;
    CK_B = 0;
    checkSum(buffer, section_num, &CK_A, &CK_B);
        
    BYTE *B_buffer = (BYTE*)malloc(sizeof(BYTE)*SIZE+4);
    B_buffer[0] = 0xB5;
    B_buffer[1] = 0x62;
    int i=0;
    for(i=0; i<section_num; i++) {
        B_buffer[i+2] = (BYTE)buffer[i];        
    }
    B_buffer[(section_num+4)-2] = (BYTE)(CK_A%(mask+1));
    B_buffer[(section_num+4)-1] = (BYTE)(CK_B%(mask+1));
    *ByteCommand = B_buffer;
    return section_num + 4; //ByteCommand element number(add B5,62,...,CK_A,CK_B)
}

/*
int main(int argc, int ** argv) {
    char str [SIZE];
    BYTE *ByteCommand=NULL;
    int section_num; //section number

    while(1) {
        scanf(" %[^\n]s",str); //Let scanf read untill it reach \n character.
        int i=0;
        section_num = generateCommand(str,&ByteCommand);
        printElement(ByteCommand, section_num);
        free(ByteCommand); 
    }
    return 0;
}
*/